package com.fungame.wordsearch;

import java.awt.Point;

import com.fungame.wordsearch.Word.Position;

/*
 * This class represents the grid
 */

public class WordGrid {
	int rows;
	int columns;
	char[][] grid; 
	public void fillGrid()
	{
		
	}
	public void init(int rows,int columns)
	{
		this.rows=rows;
		this.columns=columns;
		grid = new char[rows][columns];
	}
	 //display the grid
    public void display()
    {
    	for(int i=0;i<rows;i++)
    	{
    		System.out.println();
    		for(int j=0;j<columns;j++)
    		{
    			System.out.print(grid[i][j]+"   ");
    		}
    		
    	}
    	System.out.println();
    	
    }
    
    
    public void display(Word[] inputWordList) {
    	for(int i=0;i<rows;i++)
    	{
    		System.out.println();
    		for(int j=0;j<columns;j++)
    		{
    			System.out.print(grid[i][j]+"   ");
    		}
    		
    	}
    	System.out.println();
    	Word displayWord;
    	String found="(found)";
    	for (int i = 0; i < inputWordList.length; i++) {
    		displayWord=inputWordList[i];
    		if(displayWord.isFound())
    			System.out.println(displayWord.getWord()+found);
    		else
    			System.out.println(displayWord.getWord());
		}
	}
    
    //fill grid of size with word list
    public void fill(Word [] wordList) throws WordGridException
    {
    	for(int i=0;i<wordList.length;i++)
    	{
    		greedyTry(wordList[i]);
    	}
    	for(int i=0;i<rows;i++)
    	{
    		for(int j=0;j<columns;j++)
    		{
    			if(grid[i][j]=='\u0000'){
    			grid[i][j]=Word.LETTERS.charAt((int) (Math.random() * Word.LETTERS.length()));
    			}
    		}
    		
    	}
     	
    	
    }

    public boolean greedyTry(Word word) throws WordGridException
    {
    	boolean successful=false;
    	
    	//System.out.println("trying for word : "+word.word);
    	do{
    	Position p=word.getNewPosition();
    	boolean[][] triedLocation=new boolean[rows][columns];
    	//System.out.println("for word : "+word.getWord()+" trying for location : "+p );
    	do{
    	
    		int row=(int)(Math.random()*this.rows);
    		int column = (int)(Math.random()*this.columns);
    		triedLocation[row][column]=true;
    		int placeRow=row;
    		int placeColumn=column;
    		//System.out.println("["+row+","+column+"] : "+word.getWord()+" , "+p );
    		successful=placeWord(word,p,placeRow,placeColumn);
    		
    		
    	}while(!successful&&!exhaustedLocation(triedLocation));
    	
    	}while(!successful&&!word.exhausedPosition());
    	
    	
    	
    	if(!successful)
    	{
    		throw new WordGridException("[Error] : Word cannot be placed in grid");
    		//return false;
    	}
    	
    	
    	
    	return true;
    }
	
	private boolean placeWord(Word word, Position position, int row, int column) {
		// TODO Auto-generated method stub
			if(position==Position.horizontal)
			{
				word.setWordPosition(Position.horizontal);
				return placeHorizontal( word,  Integer.valueOf(row),  Integer.valueOf(column));
				
			}
			else if(position==Position.leftdiagonal)
			{
				word.setWordPosition(Position.leftdiagonal);
				return placeLeftDiagonal(word,    Integer.valueOf(row),  Integer.valueOf(column));
				
			}
			else if(position==Position.rightdiagonal)
			{
				word.setWordPosition(Position.rightdiagonal);
				return placeRightDiagonal(word,    Integer.valueOf(row),  Integer.valueOf(column));
				
			}
			else if(position==Position.vertical)
			{
				word.setWordPosition(Position.vertical);
				return placeVertical(word,    Integer.valueOf(row),  Integer.valueOf(column));
				
			}
		
		return false;
		
	}
	private boolean placeVertical(Word word, Integer row,
			Integer column) {
		    char[] wordChar = word.getWord().toCharArray();
			int originalRow=row;
			int originalColumn=column;
			boolean canBePlaced=true;
			word.setStart(new Point(row,column));
			try{
			for (int i = 0; i < wordChar.length; i++) {
				if(grid[row][column]=='\u0000')
				{
					//grid[row][column]=wordChar[i];
					row++;
				}
				else
				{
					
					canBePlaced=false;
				}
			}
			}
			catch(ArrayIndexOutOfBoundsException e)
			{
				canBePlaced=false;
				//throw e;
			}
			if(canBePlaced)
			{
				//System.out.println("placed word : "+word.getWord()+" at position : "+ originalRow +" , "+originalColumn+ " Position : Vertical");
				for (int i = 0; i < wordChar.length; i++) {
					
						grid[originalRow][originalColumn]=wordChar[i];
						originalRow++;
						
				}
				//System.out.println("Setting end point as  : "+originalRow+" , "+originalColumn);
				word.setEnd(new Point(originalRow-1,originalColumn));
				
			}
			return canBePlaced;
			
			
		
	}
	
	
	private boolean placeHorizontal(Word word, Integer row,
			Integer column) throws ArrayIndexOutOfBoundsException{
		int originalRow=row;
		int originalColumn=column;
		boolean canBePlaced=true;
		word.setStart(new Point(row,column));
		char[] wordChar = word.getWord().toCharArray();
		try{
		for (int i = 0; i < wordChar.length; i++) {
			if(grid[row][column]=='\u0000')
			{
				//grid[row][column]=wordChar[i];
				column++;
			}
			else
			{
				
				canBePlaced=false;
			}
		}
		}
		catch(ArrayIndexOutOfBoundsException e)
		{
			canBePlaced=false;
		}
		if(canBePlaced)
		{
			//System.out.println("placed word : "+new String(wordChar)+" at position : "+ originalRow +" , "+originalColumn+ " Position : Horizontal");
			for (int i = 0; i < wordChar.length; i++) {
				
					grid[originalRow][originalColumn]=wordChar[i];
					originalColumn++;
				
			}
			//System.out.println("Setting end point as  : "+originalRow+" , "+originalColumn);
			word.setEnd(new Point(originalRow,originalColumn-1));
		}
		return canBePlaced;

		
	}
	
	private boolean placeLeftDiagonal(Word word, Integer row,
			Integer column) throws ArrayIndexOutOfBoundsException{
		int originalRow=row;
		int originalColumn=column;
		boolean canBePlaced=true;
		char[] wordChar = word.getWord().toCharArray();
		word.setStart(new Point(row,column));
		try{
		for (int i = 0; i < wordChar.length; i++) {
			if(grid[row][column]=='\u0000')
			{
				//grid[row][column]=wordChar[i];
				column++;
				row++;
			}
			else
			{
				
				canBePlaced=false;
			}
		}
		}
		catch(ArrayIndexOutOfBoundsException e)
		{
			canBePlaced=false;
		}
		if(canBePlaced)
		{
			//System.out.println("placed word : "+new String(wordChar)+" at position : "+ originalRow +" , "+originalColumn+ " Position : LeftDiagonal");
			for (int i = 0; i < wordChar.length; i++) {
				
					grid[originalRow][originalColumn]=wordChar[i];
					originalColumn++;
					originalRow++;
				
			}
			//System.out.println("Setting end point as  : "+originalRow+" , "+originalColumn);
			word.setEnd(new Point(originalRow-1,originalColumn-1));
		}
		return canBePlaced;
		
	}
	
	private boolean placeRightDiagonal(Word word, Integer row,
			Integer column) throws ArrayIndexOutOfBoundsException{
		int originalRow=row;
		int originalColumn=column;
		boolean canBePlaced=true;
		char[] wordChar = word.getWord().toCharArray();
		word.setStart(new Point(row,column));
		
		try{
		for (int i = 0; i < wordChar.length; i++) {
			if(grid[row][column]=='\u0000')
			{
				//grid[row][column]=wordChar[i];
				row++;
				column--;
			}
			else
			{
				
				canBePlaced=false;
			}
		}
		}
		catch(ArrayIndexOutOfBoundsException e)
		{
			canBePlaced=false;
		}
		if(canBePlaced)
		{
			//System.out.println("placed word : "+new String(wordChar)+" at position : "+ originalRow +" , "+originalColumn+ " Position : RightDiagonal");
			for (int i = 0; i < wordChar.length; i++) {
				
					grid[originalRow][originalColumn]=wordChar[i];
					originalRow++;
					originalColumn--;
			}
			//System.out.println("Setting end point as  : "+originalRow+" , "+originalColumn);
			word.setEnd(new Point(originalRow-1,originalColumn+1));
		}
		return canBePlaced;
		
	}
	
	
	private boolean exhaustedLocation(boolean[][] triedLocation) {
		// TODO Auto-generated method stub
		
		
		for(int i=0;i<rows;i++)
		{
			for(int j=0;j<columns;j++)
			{
				if(triedLocation[i][j]==false) return false;
			}
		}
		//System.out.println("Locations Exhausted");
		return true;
	}
	public void highlight(Word word) {
		// TODO Auto-generated method stub
		Position wordPosition=word.getWordPosition();
		int row=(int)word.getStart().getX();
		int column=(int)word.getStart().getY(); 
		//System.out.println(" Word  : "+word.getWord()+" Position : "+wordPosition);
		if(wordPosition==Position.horizontal)
		{
			
			for(int i=0;i<word.getWord().length();i++)
			{
				//System.out.println(row+" , "+column);
				grid[row][column]=String.valueOf(grid[row][column]).toUpperCase().charAt(0);
				column++;
			}
		}
		else if(wordPosition==Position.leftdiagonal)
		{
			
			for(int i=0;i<word.getWord().length();i++)
			{
				//System.out.println(row+" , "+column);
				grid[row][column]=String.valueOf(grid[row][column]).toUpperCase().charAt(0);
				row++;
				column++;
			}
			
		}
		else if(wordPosition==Position.rightdiagonal)
		{
			for(int i=0;i<word.getWord().length();i++)
			{
				//System.out.println(row+" , "+column);
				grid[row][column]=String.valueOf(grid[row][column]).toUpperCase().charAt(0);
				row++;
				column--;
			}
			
			
		}
		else if(wordPosition==Position.vertical)
		{
			for(int i=0;i<word.getWord().length();i++)
			{
				//System.out.println(row+" , "+column);
				grid[row][column]=String.valueOf(grid[row][column]).toUpperCase().charAt(0);
				row++;
			}
			
		}
	}
	
    
	
	
	
	
	
}
